package com.cskaoyan.javase.file._1api;

import com.sun.org.apache.xpath.internal.operations.NotEquals;
import org.junit.Test;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;

/**
 * File类的常用API
 * @since 10:45
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    @Test
    public void testCreate() throws IOException {
        // File类的创建功能
        // 只负责创建文件，目录路径如果不存在，会报错而不是帮你创建
        // public boolean createNewFile()
        System.out.println(System.getProperty("user.dir"));
        File f1 = new File("b");
        // Unhandled exception: java.io.IOException
        System.out.println(f1.createNewFile());

        File f2 = new File("1\\a.txt");
        // 该方法不能用于创建目录,如果文件的中间目录不存在,会抛出异常报错
        // System.out.println(f2.createNewFile());

        // 有后缀名不能用于区分文件,没有后缀名也可以是一个文件
        File f3 = new File("a");
        System.out.println(f3.createNewFile());

        // // 只负责创建目录，但只能创建单层目录，如果是多级目录的上层不存在，则创建失败
        // public boolean mkdir()
        File f4 = new File("1");
        System.out.println(f4.mkdir());

        File f5 = new File("1\\2\\3");
        System.out.println(f5.mkdir());
        // 只负责创建目录，但可以创建多级目录，如果多级目录不存在，则帮你全部创建
        // 创建目录无脑用这个方法,无需考虑多级目录中间是否存在的问题
        // public boolean mkdirs()
        System.out.println(f5.mkdirs());

        // 有无后缀名不能用于区分文件/文件夹
        File f6 = new File("1.mp3");
        // 先判断再创建,不要无脑创建
        if (!f6.exists()) {
            System.out.println(f6.mkdirs());
        }
    }

    @Test
    public void testDelete() {
        // public boolean delete()
        File f1 = new File("a");
        // 该方法是直接通过本地方法调用操作系统API删除文件，是直接删除而不是进入回收站，开发时要慎用！！！
        System.out.println(f1.delete());

        File f2 = new File("1");
        // delete方法可以直接删除文件,但是如果是删除目录,需要保证目录为空
        System.out.println(f2.delete());

        File f3 = new File("1\\2\\3");
        System.out.println(f3.delete());
        /*
            思考:
            给定一个目录(目录非空),如何删除它呢?
                1.先进入内层目录,删除里面的文件夹和空目录
                2.最后删除掉原本的目录
            这个过程要使用递归删除:
                1.如果是文件夹/空目录直接删除
                2.如果是非空文件夹,递归删除
         */
    }

    @Test
    public void testRename() {
        // public boolean renameTo(File dest)
        // 该方法的作用是移动且附带重命名功能,它不是复制
        File srcPhoto = new File("e:\\2\\1.jpg");
        File aimPhoto = new File("e:\\2\\新垣结衣.jpg");
        System.out.println(srcPhoto.renameTo(aimPhoto));
    }

    @Test
    public void testGet() {
        // 该方法是通过一个本地方法,调用操作系统API获取一个目录下的所有文件夹,文件的名字
        // 返回一个字符串数组，这些字符串包括，此抽象的路径名表示的目录中的所有文件和文件夹的名字
        // 如果File对象表示的是一个文件/或者路径不存在，则返回null
        // 只能获取当前目录的下一层，并不是获取所有层级
        // 如果是一个空目录，返回一个长度为0的数组，而不是null
        // public String[] list()
        File f1 = new File("E:\\1");
        /*String[] listFile = f1.list();
        for (String name : listFile) {
            System.out.println(name);
        }*/


        // 返回指定File目录下的文件和文件夹的绝对路径形式的File对象数组
        // 如果File对象表示的是一个文件，则返回null
        // 只能获取当前目录的下一层，并不是获取所有层级
        // 如果是一个空目录，返回一个长度为0的数组，而不是null
        // public File[] listFiles()
        File[] files = f1.listFiles();
        for (File file : files) {
            if (!file.isFile()) {
                // 过滤掉文件夹
                continue;
            }
            // 过滤掉文件后缀中没有"txt"的文件
            if (!file.getName().endsWith(".txt")) {
                continue;
            }
            // 判断名字中是否含有"遮天"
            if (!file.getName().replaceAll(".txt", "").equals("遮天")) {
                continue;
            }
            System.out.println(file.getAbsolutePath());

        }
    }

    @Test
    public void testFilter() {
        // 带文件过滤器的listFiles方法，如下：
        // File[] listFiles(FileFilter filter)
        /*
         该方法通过传入功能接口的实现,传入了一个accept方法的实现,这就是"方法回调"将方法作为一个参数传递(扩展)
         这个被传递进来作为参数的方法,它往往表示一种规则,比如"过滤,排序,映射等"
         accept方法传入的过滤规则是: 方法返回true表示留下的,false表示过滤掉的
          */
        File f1 = new File("e:\\2");
        File[] result = f1.listFiles(new FilterRuler());
        for (File file : result) {
            System.out.println(file.getAbsolutePath());
        }
        System.out.println("-------------------");

        File[] result2 = f1.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                // 过滤的规则: 我想看奥特曼相关的资料
                return pathname.getName().contains("奥特曼");
            }
        });
        for (File file : result2) {
            System.out.println(file.getAbsolutePath());
        }

        System.out.println("--------------------------");
        // 过滤的规则: 就看新垣结衣
        File[] result3 = f1.listFiles(f -> f.isFile() && f.getName().equals("新垣结衣.jpg"));
        for (File file : result3) {
            System.out.println(file.getAbsolutePath());
        }
    }

}

class FilterRuler implements FileFilter {
    @Override
    public boolean accept(File f) {
        // 过滤的规则: 我想看学习资料相关的视频
        return f.isFile() && f.getName().endsWith(".mp4") && f.getName().contains("学习");
    }
}
